import { ObjectSystemAttribute } from "../../../Decorator/Decorator";
import { NamedSystemObject } from "../../Object/NamedObject";
import { Entity } from "../Entity/Entity";
import { InstanceQueueIndex } from "./InstanceQueueIndex";
import { ISystemType } from "./ISystemType";

// export interface IAwakeSystem<A, B, C, D> extends ISystemType {

//     run(o: Object): void;
//     run(o: Object, a: A): void;
//     run(o: Object, a: A, b: B): void;
//     run(o: Object, a: A, b: B, c: C): void;
//     run(o: Object, a: A, b: B, c: C, d: D): void;

// }

// export class IAwakeSystem<A, B, C, D> {

//     run(o: Object): void {

//     }

// }

// export abstract class AwakeSystem<T extends Entity, A, B, C, D> extends NamedObject implements IAwakeSystem<A, B, C, D> {

//     private _type: string;

//     constructor(clazz: { new(): T }) {
//         super();
//         this._type = clazz.name;
//     }

//     type() {
//         return this._type;
//     }

//     systemType() {
//         return IAwakeSystem.name;
//     }

//     getInstanceQueueIndex(): InstanceQueueIndex {
//         return InstanceQueueIndex.None;
//     }

//     run(o: Object): void;
//     run(o: Object, a: A): void;
//     run(o: Object, a: A, b: B): void;
//     run(o: Object, a: A, b: B, c: C): void;
//     run(o: Object, a: A, b: B, c: C, d: D): void;

//     run(o: Object, a?: A, b?: B, c?: C, d?: D): void {
//         this.awake(<T>o, a, b, c, d);
//     }

//     abstract awake(self: T, a?: A, b?: B, c?: C, d?: D): void;

// }

// export abstract class AwakeSystem0<T extends Entity> extends AwakeSystem<T, undefined, undefined, undefined, undefined> { }
// export abstract class AwakeSystem1<T extends Entity, A> extends AwakeSystem<T, A, undefined, undefined, undefined> { }
// export abstract class AwakeSystem2<T extends Entity, A, B> extends AwakeSystem<T, A, B, undefined, undefined> { }
// export abstract class AwakeSystem3<T extends Entity, A, B, C> extends AwakeSystem<T, A, B, C, undefined> { }
// export abstract class AwakeSystem4<T extends Entity, A, B, C, D> extends AwakeSystem<T, A, B, C, D> { }

export interface IAwake {

}

export interface IAwake1<A> {

}

export interface IAwake2<A, B> {

}

export interface IAwake3<A, B, C> {

}

export interface IAwake4<A, B, C, D> {

}

export class IAwake {

}

export class IAwake1<A> {

}

export class IAwake2<A, B> {

}

export class IAwake3<A, B, C> {

}

export class IAwake4<A, B, C, D> {

}

export interface IAwakeSystem extends ISystemType {

    Run(o: Object): void;

}

export class IAwakeSystem {

    Run(o: Object): void {

    }

}

export interface IAwake1System<A> extends ISystemType {

    Run(o: Object, a: A): void;

}

export class IAwake1System<A> {

    Run(o: Object, a: A): void {

    }

}

export interface IAwake2System<A, B> extends ISystemType {

    Run(o: Object, a: A, b: B): void;

}

export class IAwake2System<A, B> {

    Run(o: Object, a: A, b: B,): void {

    }

}

export interface IAwake3System<A, B, C> extends ISystemType {

    Run(o: Object, a: A, b: B, c: C): void;

}

export class IAwake3System<A, B, C> {

    Run(o: Object, a: A, b: B, c: C): void {

    }

}

export interface IAwake4System<A, B, C, D> extends ISystemType {

    Run(o: Object, a: A, b: B, c: C, d: D): void;

}

export class IAwake4System<A, B, C, D> {

    Run(o: Object, a: A, b: B, c: C, d: D): void {

    }

}

@ObjectSystemAttribute()
export abstract class AwakeSystem<T extends Entity> extends NamedSystemObject implements IAwakeSystem {

    constructor() {
        super();
    }

    Type() {
        return this.entityType;
    }

    SystemType() {
        return IAwakeSystem.name;
    }

    GetInstanceQueueIndex(): InstanceQueueIndex {
        return InstanceQueueIndex.None;
    }

    Run(o: Object): void {
        this.Awake(<T>o);
    }

    abstract Awake(self: T): void;

}

@ObjectSystemAttribute()
export abstract class Awake1System<T extends Entity, A> extends NamedSystemObject implements IAwake1System<A> {

    constructor() {
        super();
    }

    Type() {
        return this.entityType;
    }

    SystemType() {
        return IAwake1System.name;
    }

    GetInstanceQueueIndex(): InstanceQueueIndex {
        return InstanceQueueIndex.None;
    }

    Run(o: Object, a: A): void {
        this.Awake(<T>o, a);
    }

    abstract Awake(self: T, a: A): void;

}

@ObjectSystemAttribute()
export abstract class Awake2System<T extends Entity, A, B> extends NamedSystemObject implements IAwake2System<A, B> {

    constructor() {
        super();
    }

    Type() {
        return this.entityType;
    }

    SystemType() {
        return IAwake2System.name;
    }

    GetInstanceQueueIndex(): InstanceQueueIndex {
        return InstanceQueueIndex.None;
    }

    Run(o: Object, a: A, b: B): void {
        this.Awake(<T>o, a, b);
    }

    abstract Awake(self: T, a: A, b: B): void;

}

@ObjectSystemAttribute()
export abstract class Awake3System<T extends Entity, A, B, C> extends NamedSystemObject implements IAwake3System<A, B, C> {

    constructor() {
        super();
    }

    Type() {
        return this.entityType;
    }

    SystemType() {
        return IAwake3System.name;
    }

    GetInstanceQueueIndex(): InstanceQueueIndex {
        return InstanceQueueIndex.None;
    }

    Run(o: Object, a: A, b: B, c: C): void {
        this.Awake(<T>o, a, b, c);
    }

    abstract Awake(self: T, a: A, b: B, c: C): void;

}

@ObjectSystemAttribute()
export abstract class Awake4System<T extends Entity, A, B, C, D> extends NamedSystemObject implements IAwake4System<A, B, C, D> {

    constructor() {
        super();
    }

    Type() {
        return this.entityType;
    }

    SystemType() {
        return IAwake4System.name;
    }

    GetInstanceQueueIndex(): InstanceQueueIndex {
        return InstanceQueueIndex.None;
    }

    Run(o: Object, a: A, b: B, c: C, d: D): void {
        this.Awake(<T>o, a, b, c, d);
    }

    abstract Awake(self: T, a: A, b: B, c: C, d: D): void;

}